package com.fc.remoting.client;

import com.fc.remoting.codec.RemotingMessageDecoder;
import com.fc.remoting.codec.RemotingMessageEncoder;
import com.fc.remoting.handler.RemotingClientMessageHandler;

import io.netty.bootstrap.Bootstrap;
import io.netty.channel.Channel;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioSocketChannel;

public enum RemotingClient {
	INSTANCE;
	private EventLoopGroup group = new NioEventLoopGroup();
	private Bootstrap boot = new Bootstrap();

	RemotingClient() {
		boot.group(group);
		boot.channel(NioSocketChannel.class);
		boot.option(ChannelOption.TCP_NODELAY, true);
		boot.option(ChannelOption.SO_TIMEOUT, 5000);
		boot.handler(new ChannelInitializer<Channel>() {
			@Override
			protected void initChannel(Channel ch) throws Exception {
				ch.pipeline().addLast(new ClientChannelManager());
				ch.pipeline().addLast(new RemotingMessageDecoder());
				ch.pipeline().addLast(new RemotingMessageEncoder());
				ch.pipeline().addLast(new RemotingClientMessageHandler());
			}
		});
	}

	public boolean connect(String address, int port) throws InterruptedException {
		ChannelFuture future = null;

		future = boot.connect(address, port).sync();
		if (future.isSuccess()) {
			Channel channel = future.channel();
			ClientChannelManager.addChannel(IRemotingClient.REMOTING_CLIENT_ID, channel);
			return true;
		}
		return false;
	}

	public void closeEventLoopGroup() {
		group.shutdownGracefully();
	}
}
